
// ChildView.cpp : implementation of the CChildView class
//

#include "stdafx.h"
#include "FluidSimulator.h"
#include "ChildView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CChildView

CChildView::CChildView()
{
	glShadeModel(GL_SMOOTH);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_COLOR_MATERIAL);

	GLfloat light_ambient[] =  {1.0f, 1.0f, 1.0f, 1.0f};
    GLfloat light_diffuse[] =  {1.0f, 1.0f, 1.0f, 1.0f};
    GLfloat light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
    GLfloat light_position[] = {0.0f, 0.0f, 1.5f, 0.0f};

	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

	pause = false;
	cont = false;
	x = 30.;
}

CChildView::~CChildView()
{
}


BEGIN_MESSAGE_MAP(CChildView, COpenGLWnd)
	ON_WM_PAINT()
	ON_WM_KEYUP()
	ON_WM_KEYDOWN()
END_MESSAGE_MAP()



// CChildView message handlers

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
{
	if (!COpenGLWnd::PreCreateWindow(cs))
		return FALSE;

	cs.dwExStyle |= WS_EX_CLIENTEDGE;
	cs.style &= ~WS_BORDER;
	cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
		::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);

	return TRUE;
}


void CChildView::OnGLDraw(CDC * pDC)
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f) ;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

	int width, height;
    GetSize(width, height);
    GLdouble aspectratio = GLdouble(width) / GLdouble(height);

	gluPerspective(25.,         // Vertical FOV degrees.
        aspectratio, // The aspect ratio.
        10.,         // Near clipping 40/130
        200.);       // Far clipping

	glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

	gluLookAt(30., 25., 50.,    // eye x,y,z
        0., 0., 0.,       // center x,y,z
        0., 1., 0.);      // Up direction

	glEnable(GL_DEPTH_TEST);

    // Cull backfacing polygons
    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);

    // Draw a coordinate axis
    /*glColor3d(0., 1., 1.);

    glBegin(GL_LINES);
		glVertex3d(0., 0., 0.);
		glVertex3d(12., 0., 0.);
		glVertex3d(0., 0., 0.);
		glVertex3d(0., 12., 0.);
		glVertex3d(0., 0., 0.);
		glVertex3d(0., 0., 12.);
    glEnd();*/


	//Set up aspect ratio, can change this if/when we need to
    /*glOrtho(-width/2,   // left
        width/2,   // right
        -height/2,   // bottom
        height/2,   // top
        1.0,  // near
        -1.0);  // far*/


	mPSystem.SetLighting();
	if (!pause) 
		mPSystem.Simulate();
	else if (cont)
	{
		mPSystem.Simulate();
		cont = false;
	}
	//x += .2;
	mPSystem.Draw();

	glFlush();

	Invalidate();
}



afx_msg void CChildView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	//int x = -1;
    COpenGLWnd::OnKeyDown(nChar, nRepCnt, nFlags);

	switch(nChar)
	{
	case 81: //Should be Q?
		PostQuitMessage(0);
		break;
	case 87: //Activates our debug mode
		mPSystem.debug = true;
		break;
	case 80: // p key
		if (pause)
			pause = false;
		else
			pause = true;
		break;
	case VK_RIGHT:	//Right arrow - simulate one time step if pause = true
		if (pause)
			cont = true;
		break;
	case VK_NUMPAD1:
	case 0x31:	// 1
		//For the Leap Frog integration method
		mPSystem = CParticleSystem(9, 9, 9, 1);
		mPSystem.leapFrog = true;
		break;
	case VK_NUMPAD2:
	case 0x32:	// 2
		//For the Euler integration method
		mPSystem = CParticleSystem(9, 9, 9, 1);
		mPSystem.leapFrog = false;
		break;
	case VK_NUMPAD3:
	case 0x33:	// 3
		//Leapfrog & smaller box
		mPSystem = CParticleSystem(3, 12, 3, 2); //true = second example
		mPSystem.leapFrog = true;
		break;
	case VK_NUMPAD4:
	case 0x34:	// 4
		//For the Euler integration method
		mPSystem = CParticleSystem(3, 12, 3, 2);
		mPSystem.leapFrog = false;
		break;
	case 0x35:	// 5
		mPSystem = CParticleSystem(3, 12, 3, 3);
		mPSystem.leapFrog = true;
		break;
	case 0x36:	// 6
		mPSystem = CParticleSystem(3, 12, 3, 3);
		mPSystem.leapFrog = false;
		break;
	case 0x4C:	// L key
		//Add interactive force left
		mPSystem.interaction = true;
		mPSystem.externalForce += Vector3df(-0.5f, 0.f, 0.5f);
		break;
	case 0x52:	// R key
		//Add interactive force right
		mPSystem.interaction = true; 
		mPSystem.externalForce += Vector3df(0.5f, 0.f, -0.5f);
		break;
	case 0x55:	// U key
		//Add interactive force up
		mPSystem.interaction = true;
		mPSystem.externalForce += Vector3df(0.f, 7.f, 0.f);
		break;
	case 0x44:	// D key
		mPSystem.interaction = true;
		mPSystem.externalForce += Vector3df(0.f, -0.2f, 0.f);
		break;
	case 0x20:	// spacebar
		// Add stream of particles (simulate pouring)
		mPSystem.add = true;
		break;
	default:
		//x = -1;//Nothing right now
		break;
	}
}